<template>
  <div class="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
import * as Cesium from "cesium";
import { onMounted, ref ,reactive} from "vue";
import GUI from "lil-gui";

const cesiumContainer = ref(null);
let model=reactive(null);
let scene=reactive(null);
let viewer=reactive(null);
let camera=reactive(null);
const viewModel = {
  color: "White",
  colors: ["White", "Red", "Green", "Blue", "Yellow", "Gray"],
  alpha: 1.0,
  colorBlendModel: "Highlight",
  colorBlendModes: ["Highlight", "Replace", "Mix", "WeightedSum"],
  colorBlendAmount: 0.5, 
  model:"/public/models/CesiumAir/Cesium_Air.glb",
  models:{
      "客机":"/public/models/CesiumAir/Cesium_Air.glb" 
    , "无人机": "/public/models/CesiumDrone/CesiumDrone.glb"
    ,"装甲车": "/public/models/GroundVehicle/GroundVehicle.glb"
    ,"快餐车": "/public/models/CesiumMilkTruck/CesiumMilkTruck.glb"
    ,"测试人": "/public/models/CesiumMan/Cesium_Man.glb"
  },
  cameraHeading:0
};

let gui = new GUI();
let kexuan=gui.add(viewModel, "colorBlendAmount",0,1,.01).name("颜色强度MIX")
    .onChange((e) => {
      console.log("颜色强度 MIX", e);  
      model.colorBlendAmount = Number(e); 
    }).disable();

  gui.add(viewModel, "colorBlendModel", viewModel.colorBlendModes).name("定义颜色如何与模型混合")
  .onChange((e) => {
    console.log("定义颜色如何与模型混合", e); 
    model.colorBlendMode=getColorBlendMode(e);
    if(model.colorBlendMode==Cesium.ColorBlendMode.MIX) 
    kexuan.enable()
    else kexuan.disable(); 
  }) 
 
  gui.add(viewModel,"color",viewModel.colors).name("颜色").onChange(e=>{
    console.log("选择颜色",e);
    model.color=Cesium.Color.fromAlpha(getColor(e),viewModel.alpha)
  })
  gui.add(viewModel,"alpha",0,1,.01).name("透明度").onChange(e=>{
    console.log("透明度",e);
    model.color=Cesium.Color.fromAlpha(getColor(viewModel.color),e)
  })
 gui.add(viewModel,"model",viewModel.models).onChange(e=>{
    console.log("选择模型",e); 
    createModel(e);
 })

//  gui.add(viewModel,"cameraHeading",0,360,1).onChange(e=>{
//      camera.lookAt(
//           model.boundingSphere.center,
//           new Cesium.HeadingPitchRange(Cesium.Math.toRadians(e), Cesium.Math.toRadians(230),200)
//         );
//  })

 

// 相当于密钥，申请使用下边链接中的数据时需要用到
Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyOTQ0YTExZS02N2Y4LTQ2OTMtOWQ4NS1mNzE3ZWMwYTNmNmEiLCJpZCI6NDM1OCwiaWF0IjoxNjI4MTQzMjE1fQ.csECCT352LHVhak2sJlWYXw_gr7U-AqdQ9UMvtfOeg8";

// Cesium.ArcGisMapService.defaultAccessToken = '你的token';
function getColorBlendMode(colorBlendMode) {
    console.log("getColorBlendMode:", colorBlendMode);
    return Cesium.ColorBlendMode[colorBlendMode.toUpperCase()];
  }

  function getColor(color) {
    console.log("getColor:", color);
    return Cesium.Color[color.toUpperCase()];
  } 

  ////创建模型
  async function createModel(url, height, heading, pitch, roll) {
    height = Cesium.defaultValue(height, 0.0);
    heading = Cesium.defaultValue(heading, 0.0);
    pitch = Cesium.defaultValue(pitch, 0);
    roll = Cesium.defaultValue(roll, 0);

     //由世界坐标转化成地球坐标
    const origin = Cesium.Cartesian3.fromDegrees(119, 40, height);

    //模型姿态 航向角度，正东向南，俯仰角，上下，翻滚自身
    const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); 

    //由姿态矩阵计算出世界坐标
    const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
      origin,
      hpr
    );

    console.log("origin",origin);
    console.log("hpr",hpr);
    console.log("modelMatrix",modelMatrix);

    scene.primitives.removeAll(); //移除掉所有实体
    try {
        model = scene.primitives.add(
        await Cesium.Model.fromGltfAsync({
          url: url,
          modelMatrix: modelMatrix, //模型姿态矩阵
          minimumPixelSize: 128, //模型最小像素尺寸
        })
      ); 

      //模型加载完成事件
      model.readyEvent.addEventListener(() => {  
        model.color = Cesium.Color.fromAlpha(
          getColor(viewModel.color),
          Number(viewModel.alpha)
        );
        model.colorBlendMode = getColorBlendMode(viewModel.colorBlendModel); //颜色混合模式
        model.colorBlendAmount = Number(viewModel.colorBlendAmount); //颜色混合权重
        //添加动画
        model.activeAnimations.addAll({
          multiplier: 0.5, //速度
          loop: Cesium.ModelAnimationLoop.REPEAT, //循环播放
          onComplete: () => {
            console.log("动画播放完毕");
          },
        });

        camera = viewer.camera; // 获取相机对象
        let near = camera.frustum.near; //近裁剪面距离 默认0.1
        const controller = scene.screenSpaceCameraController; //获取相机控制器
        let radius = model.boundingSphere.radius; //模型半径
        const r = 2.0 * Math.max(radius, near); //模型半径

        controller.minimumZoomDistance = r * 0.5; //最小缩放距离

        const center = model.boundingSphere.center; // 获取模型中心点
        const heading = Cesium.Math.toRadians(230); //航向角
        const pitch = Cesium.Math.toRadians(-20); //俯仰角
        //
        


        camera.lookAt(
          center,
          new Cesium.HeadingPitchRange(heading, pitch, r * 2)
        );
      });
    } catch (error) {
      console.log(error);
    }
  }

onMounted(async () => {
   viewer = new Cesium.Viewer(cesiumContainer.value, {
    baseLayerPicker: false, // 如果设置为false，将不会创建右上角图层按钮。
    fullscreenButton: false, // 如果设置为false，将不会创建右下角全屏按钮。
    vrButton: false, // 如果设置为false，将不会创建VR应用场景
    geocoder: false, // 如果设置为false，将不会创建右上角查询(放大镜)按钮。
    homeButton: false, // 如果设置为false，将不会创建右上角主页(房子)按钮。
    infoBox: false, // 是否显示点击要素之后显示的信息,cesium中的沙盒开关
    sceneModePicker: false, // 如果设置为false，将不会创建右上角投影方式控件(显示二三维切换按钮)。
    selectionIndicator: false, // 获取当选定实体更改时引发的事件。
    navigationHelpButton: false, // 如果设置为false，则不会创建右上角帮助(问号)按钮。
    navigationInstructionsInitiallyVisible: false, // 如果帮助说明最初应该是可见的，则为true；如果直到用户明确单击该按钮，则不显示该说明，否则为false。
    timeline: true, // 如果设置为false，则不会创建正下方时间轴小部件。
    scene3DOnly: true, // 为 true 时，每个几何实例将仅以3D渲染以节省GPU内存。
    animation: true, // 如果设置为false，将不会创建左下角动画小部件。
    shouldAnimate: false, // 默认true ，否则为 false 。此选项优先于设置 Viewer＃clockViewModel 。
    // ps. Viewer＃clockViewModel 是用于控制当前时间的时钟视图模型。我们这里用不到时钟，就把shouldAnimate设为false
    sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
    requestRenderMode: false, // 启用请求渲染模式，不需要渲染，节约资源吧
    fullscreenElement: document.body, // 全屏时渲染的HTML元素 暂时没发现用处，虽然我关闭了全屏按钮，但是键盘按F11 浏览器也还是会进入全屏
    shadows: true,
  });

  //获取场景对象
   scene = viewer.scene; 
  
  

  const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
  handler.setInputAction((e) => {
    const pick = scene.pick(e.endPosition);
    if (
      Cesium.defined(pick) &&
      Cesium.defined(pick.node) &&
      Cesium.defined(pick.mesh)
    ) {
      console.log(`node:${pick.node.name},mesh:${pick.mesh.name}`);
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);



  const height = 500000.0;
  const heading = 0.0;
  const pitch = Cesium.Math.toRadians(10.0);
  const roll = Cesium.Math.toRadians(-20.0);
  createModel(
    "/public/models/CesiumAir/Cesium_Air.glb",
    height,
    heading,
    pitch,
    roll
  );
});
</script> 
<style scoped>
.cesiumContainer {
  width: 100%;
  height: 100vh;
}
</style>
